Alumnos: Cristhian Rodríguez y Jesus Perucha

1. Preparar los datos para aplicar algoritmos de ML


In [1]:
import sys #only needed to determine Python version number

# Handle table-like data and matrices
import numpy as np
import pandas as pd

# Visualisation
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.pylab as pylab
import seaborn as sns

# Enable inline plotting
%matplotlib inline

# Modelo
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split

print("ok")


ok

1.1 Importamos las librerias que vamos a necesitar


In [8]:
# Realizamos la lectura del fichero y incluimos en el fichero el nombre de las columnas
names_features = [
'age',             # Edad del individuo: [17 - 90] media 38, 
'type_employer',   # Tipo de trabajo : [ State-gov, Self-emp-not-inc, Private, Federal-gov, Local-gov, ?, Self-emp-inc, Without-pay, Never-worked ]
'fnlwgt',          # Numero de personas encuestadas
'education',       # Nivel mas alto de educacion para el individuo
'education-num',   # Nivel mas alto de educacion en forma numerica [1 - 16]
'marital-status',  # Estado civil de la persona: [ Never-married, Married-civ-spouse, Divorced, Married-spouse-absent, Separated, Married-AF-spouse, Widowed ]
'occupation',      # Ocupacion de la persona: [ Adm-clerical, Exec-managerial, Handlers-cleaners, Prof-specialty, Other-service, Sales, Craft-repair, Transport-moving, Farming-fishing, Machine-op-inspct, Tech-support, ?, Protective-serv, Armed-Forces, Priv-house-serv']
'relationship',    # Relacion familiar: [ Not-in-family, Husband, Wife, Own-child, Unmarried, Other-Relative]
'race',            # Raza de un individuo: [ White, Black, Asian-Pac-Islander, Amer-Indian-Eskimo, Other ]
'sex',             # Sexo de un individuo : [ Male, Female]
'capital_gain',    # Ganancias de capital : [ 0 - 99999 ]
'capital_loss',    # Perdidas de caapital : [ 0 - 4356 ]
'hours-per-week',  # Horas trabajadas por semana : [ 1 - 99 ]
'native-country',  # Pais de origen de la persona : [   ]
'income'           # Indica si una persona gana o no mas de 50.000        
]
df = pd.read_csv('adult.txt' , header=None, names=names_features)
df.head(3)
#print('ok')


Out[8]:
age type_employer fnlwgt education education-num marital-status occupation relationship race sex capital_gain capital_loss hours-per-week native-country income
0 39 State-gov 77516 Bachelors 13 Never-married Adm-clerical Not-in-family White Male 2174 0 40 United-States <=50K
1 50 Self-emp-not-inc 83311 Bachelors 13 Married-civ-spouse Exec-managerial Husband White Male 0 0 13 United-States <=50K
2 38 Private 215646 HS-grad 9 Divorced Handlers-cleaners Not-in-family White Male 0 0 40 United-States <=50K

In [ ]:
columna_unica = df['native-country'].unique()

In [6]:
# Obtenemos las edades de las personas
edad = df['age']

# Hacemos una busqueda con las edades que pertenezcan a un rango
edad.where( edad < 30 ).where( edad > 18).count()
print('ok')
#",".join(ocupacion )


ok

• Agrupa los países en grupos

Agrupamos las personas por ciudad, Las que son de EEUU en uno y los que no son de EEUU en otro


In [8]:
def isEEUU(x):
     
    if x == ' United-States':
        return 1
    else :
        return 0
  
# Aplicamos una funcion a la columna, para convertir los valores en enumerados
enum_isEEUU = df["native-country"].apply(isEEUU)

# Cramos la nueva columna enum_isEEUU con los datos anteriores
df["enum_isEEUU"] = enum_isEEUU    
print('ok')


ok

• Mapeamos las razas


In [43]:
from sklearn import preprocessing
le = preprocessing.LabelEncoder()

# Mapea los valores unicos de type_employer a enumerados
le.fit(df["race"].unique())

# Muestra como lo ha mapeado
print(list(le.classes_))

# Aplicamos una funcion a la columna, para convertir los valores en enumerados
enum_razas = le.transform( df["race"])

# Cramos la nueva columna enum_razas con los datos anteriores
df["enum_race"] = enum_razas

#muestra la inversa
#list(le.inverse_transform(df["enum_razas"].head()))
print('ok')


[' Amer-Indian-Eskimo', ' Asian-Pac-Islander', ' Black', ' Other', ' White']
ok

• Mapea el tipo de trabajo


In [20]:
from sklearn import preprocessing
le = preprocessing.LabelEncoder()

# Mapea los valores unicos de type_employer a enumerados
le.fit(df["type_employer"].unique())

# Transformamos la columna type_employer con 'labelEncoder' en enumerados
enum_type_employer = le.transform( df["type_employer"])

# Cramos la nueva columna enum_type_employer con los datos anteriores
df["enum_type_employer"] = enum_type_employer
print('ok')


ok

• Mapea el tipo de familia


In [102]:
from sklearn import preprocessing
le = preprocessing.LabelEncoder()

le.fit(df["relationship"].unique())

enum_relationship = le.transform( df["relationship"])

df["enum_relationship"] = enum_relationship

#muestra la inversa
#list(le.inverse_transform(df["enum_rel"].head()))
print('ok')


ok

• Mapea la ocupacion


In [12]:
from sklearn import preprocessing
le = preprocessing.LabelEncoder()
le.fit(df["occupation"].unique())
df["enum_occupation"] = le.transform( df["occupation"])
print('ok')


ok

• Mapea las ganancias (>50k o <=50k)


In [13]:
from sklearn import preprocessing
le = preprocessing.LabelEncoder()
le.fit(df["income"].unique())

# Muestra como lo ha mapeado
print(list(le.classes_))

df["enum_income"] = le.transform( df["income"])
print('ok')


[' <=50K', ' >50K']
ok

• Mapea el sexo


In [14]:
from sklearn import preprocessing
le = preprocessing.LabelEncoder()
le.fit(df["sex"].unique())

# Muestra como lo ha mapeado
print(list(le.classes_))

df["enum_sex"] = le.transform( df["sex"])
print('ok')


[' Female', ' Male']
ok

• Mapea el estado civil de cada persona


In [15]:
from sklearn import preprocessing
le = preprocessing.LabelEncoder()
le.fit(df["marital-status"].unique())

# Muestra como lo ha mapeado
print(list(le.classes_))

df["enum_marital-status"] = le.transform( df["marital-status"])
print('ok')


[' Divorced', ' Married-AF-spouse', ' Married-civ-spouse', ' Married-spouse-absent', ' Never-married', ' Separated', ' Widowed']
ok

2. Haz visualizaciones de diferentes valores con seaborn.

Describe lo que ves en las visualizaciones


In [49]:
plt.title('Personas que ganan mas de 50 o lo contrario', y=1.1, size=15)
sns.countplot('income', data=df)


Out[49]:
<matplotlib.axes._subplots.AxesSubplot at 0x15766cf8>

In [7]:
plt.title('Numero de personas que ganan mas o menos de 50k diferenciadas por sexos', size=20, y=1.1)
sns.countplot(x = 'income', hue='sex', data=df)


Out[7]:
<matplotlib.axes._subplots.AxesSubplot at 0xc8325f8>

In [27]:
plt.title('media de las que ganan mas o menos de 50k diferenciadas por sexos', size=20, y=1.1)
sns.barplot(x = 'income', y='enum_sex',data=df)


Out[27]:
<matplotlib.axes._subplots.AxesSubplot at 0xec9a518>

In [51]:
plt.title('Numero de personas que ganan mas o menos de 50k diferenciadas por el tipo de trabajador', size=20, y=1.1)
sns.countplot(x = 'income', hue='type_employer', data=df)


Out[51]:
<matplotlib.axes._subplots.AxesSubplot at 0x15a165c0>

En esta grafica podemos ver que hay menos mujeres que ganan mas de 50k.


In [52]:
plt.title('Media de las ganancias diferenciadas por el tipo de trabajador', size=10, y=1.1)
sns.barplot(x = 'enum_type_employer', y='enum_income', data=df, hue="type_employer")


Out[52]:
<matplotlib.axes._subplots.AxesSubplot at 0x146b1b00>

Esta grafica nos muestra que los que mas ganan son los trabajadores con los puestos:

  1. Self-emp-not-inc
  2. Federal-gov
  3. Local-gov

In [54]:
plt.title('Numero de personas que ganan mas o menos de 50k diferenciadas por la raza', size=20, y=1.1)
sns.countplot(x = 'income', hue='race', data=df)


Out[54]:
<matplotlib.axes._subplots.AxesSubplot at 0x16e3b5f8>

Aqui podemos ver que las personas de raza blanca son las mas numerosas. Del mismo modo se ve que los blancos son los que ganan mas de 50k.


In [66]:
plt.title('Media de las ganancias diferenciadas por la raza', size=20, y=1.1)
sns.barplot(x = 'enum_race', y='enum_income', data=df, hue="race")


Out[66]:
<matplotlib.axes._subplots.AxesSubplot at 0x196aae80>

En cambio al hacer la media de las personas nos da como resultado que que los que mas ganan son los asiaticos.


In [68]:
plt.title('Numero de personas que ganan mas de 50k diferenciadas por la relacion familiar', size=20, y=1.1)
sns.countplot(x = 'income', hue='relationship', data=df)


Out[68]:
<matplotlib.axes._subplots.AxesSubplot at 0x19c18748>

En esta grafica se aprecia que el numero de personas que ganan mas de 50k son los 'maridos'


In [65]:
plt.title('Media de las ganancias diferenciadas por la relacion familiar', size=20, y=1.1)
sns.barplot(x = 'enum_relationship', y='enum_income', data=df, hue="relationship")


Out[65]:
<matplotlib.axes._subplots.AxesSubplot at 0x19151b38>

Aqui podemos ver las 'esposas' tienen la mayor media de ganancias (> 50k)


In [72]:
plt.title('Numero de personas que ganan mas de 50k diferenciadas por la ocupacion', size=20, y=1.1)
sns.countplot(x = 'income', hue='occupation', data=df)


Out[72]:
<matplotlib.axes._subplots.AxesSubplot at 0x18a9e6d8>

In [77]:
plt.title('Media de las ganancias diferenciadas por la relacion familiar', size=20, y=1.1)
sns.barplot(x = 'enum_occupation', y='enum_income', data=df, hue="occupation")


Out[77]:
<matplotlib.axes._subplots.AxesSubplot at 0x1fbe1278>

In [83]:
plt.title('Distribucion de las horas por semana', size=20, y=1.1)
sns.distplot(df['hours-per-week'])
df['hours-per-week'].describe()


Out[83]:
count    32561.000000
mean        40.437456
std         12.347429
min          1.000000
25%         40.000000
50%         40.000000
75%         45.000000
max         99.000000
Name: hours-per-week, dtype: float64

Podemos observar que la mayoria de las personas trabajan 40h a la semana

Correlacion


In [87]:
colormap = plt.cm.viridis
plt.figure(figsize=(12, 12))
plt.title("Correlacion entre todas las features", y=1.05, size=20)
sns.heatmap(df.corr(), linewidths=0.1, square=True, vmax=1.0, annot=True, cmap=colormap)


Out[87]:
<matplotlib.axes._subplots.AxesSubplot at 0x1fd505c0>

In [103]:
features = ["hours-per-week","enum_sex","enum_type_employer","enum_race","enum_income","age","education-num","capital_gain","capital_loss","enum_marital-status","enum_occupation","enum_relationship"]

X = df[features]       # features
var_correlations = {c: np.abs(X['enum_income'].corr(df[c])) for c in X.columns}

corr_dataframe = pd.DataFrame(var_correlations, index=['Correlation']).T.sort_values(by='Correlation')
plt.title('Correlacion entre las features y la ganancia', y=1.1, size=20)
plt.barh(range(corr_dataframe.shape[0]), corr_dataframe['Correlation'].values, tick_label=X.columns.values)


Out[103]:
<Container object of 12 artists>

In [19]:
g = sns.FacetGrid(df, col='enum_income')
g.map(plt.hist, 'education-num', bins=20)


Out[19]:
<seaborn.axisgrid.FacetGrid at 0x10d89d68>

4. Utiliza random forest con diferentes parámetros, diferentes features, y cross_validation para conseguir el mejor modelo posible.


In [57]:
from sklearn import svm
from sklearn.model_selection import cross_val_score
import pandas as pd
import numpy as np

# modelo
modelo = RandomForestClassifier(n_estimators=9, min_samples_split=2 ,min_samples_leaf =1, n_jobs = 49)

# Seleccionamos las features con las que vamos a usar el algoritmo
features = ["education-num","capital_gain","capital_loss","enum_marital-status","enum_occupation","enum_relationship"]

X = df[features]       # features
y = df["enum_income"]  # targets

#SCORE
scores = cross_val_score(modelo, X, y, cv = 5 )
print(scores.mean())


0.857651928236

In [96]:
from sklearn.grid_search import GridSearchCV
# define the parameter values that should be searched
N_estimators = list(range(1, 20))
Min_samples_split= list(range(2, 10))
Min_samples_leaf = list(range(1, 2))
N_jobs = list(range(1, 20))
print(Min_samples_leaf)
print(Min_samples_split)


[1]
[2, 3, 4, 5, 6, 7, 8, 9]

In [97]:
# create a parameter grid: map the parameter names to the values that should be searched
param_grid = dict(n_estimators=N_estimators, min_samples_split=Min_samples_split ,min_samples_leaf =Min_samples_leaf, n_jobs = N_jobs)

In [ ]:
# instantiate and fit the grid
grid = GridSearchCV(modelo, param_grid, cv=5, scoring='accuracy')
grid.fit(X, y)

In [ ]:
# view the complete results
grid.grid_scores_

PRUEBAS


In [ ]:


In [ ]: